package com.tang.multi.v2;

import lombok.extern.slf4j.Slf4j;

import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * @author Tang
 * @classname Acceptor
 * @description [ 请求接收 ]
 * @date 2021/8/10 14:00
 */
@Slf4j
public class Acceptor implements Runnable {

    private final int core = 3;

    private int index = 0;

    private SubReactor[] subReactors = new SubReactor[core];

    /**
     * 业务处理
     */
    private Selector[] selectors = new Selector[core];

    private ServerSocketChannel serverSocketChannel;

    public Acceptor(ServerSocketChannel serverSocketChannel) throws Exception{
        this.serverSocketChannel = serverSocketChannel;
        for (int i = 0; i < this.core; i++) {
            selectors[i] = Selector.open();
            subReactors[i] = new SubReactor(selectors[i],i);
            Thread thread = new Thread(subReactors[i]);
            thread.setDaemon(true);
            thread.start();
        }
    }

    @Override
    public void run() {
        try {
            // 处理连接
            SocketChannel socketChannel = this.serverSocketChannel.accept();
            socketChannel.configureBlocking(false);
            SubReactor subReactor = this.subReactors[this.index % this.core];
            Selector selector = this.selectors[this.index % this.core];
            log.info("当前连接{},注册到{}号subRector上...", socketChannel.hashCode(), subReactor.getId());
            // 取消 SubReactor 线程的阻塞
            selector.wakeup();
            // 注册 一个 selector
            SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_READ);
            // 附加 WorkHandler
            selectionKey.attach(new WorkHandler(socketChannel,selector,selectionKey));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}